﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;
using Spring.Data.NHibernate.Generic;
using Spring.Data.NHibernate.Generic.Support;

namespace Dukou.Dao.Implement
{
    using Dukou.Domain;

    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TId"></typeparam>
    public class NHibernateDao<T, TId> : HibernateDaoSupport, INHibernateDao<T, TId> where T : IEntity<TId>
    {
        /// <summary>
        /// 通过指定标识获取持久态对象实例
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public T FindById(TId id)
        {
            return this.HibernateTemplate.Get<T>(id);
        }

        /// <summary>
        /// 获取指定类型的所有持久态对象
        /// </summary>
        /// <returns></returns>
        public IList<T> SelectAll()
        {
            return this.HibernateTemplate.LoadAll<T>();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="start"></param>
        /// <param name="number"></param>
        /// <returns></returns>
        public IList<T> SelectAll(int start, int number)
        {
            return this.HibernateTemplate.ExecuteFind<T>(delegate(ISession session)
            {
                return session.CreateCriteria(typeof(T), "d")
                    .SetFetchSize(number)
                    .SetFirstResult(start)
                    .List<T>();
            });
        }

        /// <summary>
        /// 保存瞬时态对象实例
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public TId Save(T entity)
        {
            return (TId)this.HibernateTemplate.Save(entity);
        }

        /// <summary>
        /// 保存或更新持久态对象实例
        /// </summary>
        /// <param name="entity"></param>
        public void SaveOrUpdate(T entity)
        {
            this.HibernateTemplate.SaveOrUpdate(entity);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        public void Update(T entity)
        {
            this.HibernateTemplate.Update(entity);
        }

        /// <summary>
        /// 删除指定持久态对象实例
        /// </summary>
        /// <param name="entity"></param>
        public void Delete(T entity)
        {
            this.HibernateTemplate.Delete(entity);
        }

        /// <summary>
        /// 通过指定标识删除数据库记录
        /// </summary>
        /// <param name="type"></param>
        /// <param name="id"></param>
        public void Delete(Type type, TId id)
        {
            this.HibernateTemplate.Execute<int>(delegate(ISession session)
            {
                session.Delete(string.Format("from {0} e where e.Id = ?", type.FullName.Split('.').Last()), id);

                return 0;
            });
        }

        /// <summary>
        /// 从会话缓存中移除指定对象
        /// </summary>
        /// <param name="entity"></param>
        public void Evict(T entity)
        {
            this.HibernateTemplate.Evict(entity);
        }

        /// <summary>
        /// 从会话缓存移除所有对象，并且取消所有保存、修改、删除
        /// </summary>
        public void Clear()
        {
            this.HibernateTemplate.Clear();
        }

        /// <summary>
        /// 拷贝指定对象到持久态对象（一样的标识）。
        /// 如果当前会话中没有持久态对象，会从数据库中加载。
        /// 返回持久态对象。
        /// 如果指定对象是未保存，保存指定对象副本并返回新的持久态对象。
        /// 指定对象不会和会话建立关系。
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T Merge(T entity)
        {
            return (T)this.HibernateTemplate.Merge(entity);
        }
    }
}
